5 de Mayo de 2022

Objetivo

Entender cómo usar los datos geolocalizados para problemas inmobiliarios

En especial

  • Entender cuáles son los factores que importan más en el precio de una casa

  • Modelizar el precio de un inmueble de acuerdo a variables geo-espaciales

  • Visualizar el mercado de oferta de viviendas

Location Intelligence en el mercado inmobiliario

Uno de los sectores en el que Location Intelligence es más importante es del mercado inmobiliario.

De hecho una de las máximas del mercado inmobiliario es que las tres cosas que más importan para el precio de una casa son:

“Location, Location, Location”

Entender mejor cómo las variables geo-espaciales influyen en el precio de un inmueble y en sus cambios nos permite:

  • Manejar mejor las carteras de inmuebles (inversores)

  • Detectar oportunidades de inversión (inversores, compradores)

  • Mejorar las promociones de nuevos inmuebles

Location Intelligence en el mercado inmobiliario

Hay mucha literatura sobre cuáles son las variables del barrio y de la ciudad que más afectan al precio de un inmueble. Por ejemplo:

  • La distancia al centro

  • El tener una parada de metro cerca

  • El hecho de que sea una zona nueva

  • Que haya otros medios de transporte

  • Que haya un parque cerca. O un supermercado

  • O que no haya cierto tipos de negocio cerca

  • El nivel de ruido/contaminación de la zona, etc.

Todas estas variables son de Location Intelligence.

Location Intelligence en el mercado inmobiliario

La visualización y sobre todo la modelización de cómo impactan estas variables en el precio es lo que hace que Location Intelligence sea tan importante en el mercado inmobiliario.

En España hay varias empresas que dan este tipo de servicios de Location Intelligence

y en otros países:

Location Intelligence en el mercado inmobiliario

Y qué variables son las más importantes? Muchas. Recomiendo leer el libro editado por Zillow

  • Propiedades de la casa
    • Superficie
    • Número de habitaciones
    • Instalaciones
    • Etc.
  • Propiedades del vecindario
    • Transporte
    • Zona urbana/suburbana
    • Tiendas
    • Instalaciones
    • Etc.

Taller: Precio de vivienda en Madrid

Vamos a ver un ejemplo de cómo utilizar variables geo-espaciales para enteder el precio de la vivienda en Madrid. Para ello vamos a utilizar una lista de precio de viviendas.

precios_vivienda <- read.csv("./data/precios_vivienda.csv")
head(precios_vivienda,4)
##   bathrooms exterior  price rooms size longitude latitude
## 1         1     TRUE  56050     3   60 -3.614164 40.40848
## 2         2     TRUE 160000     3  107 -3.641696 40.38688
## 3         2     TRUE 645000     3  154 -3.674424 40.42397
## 4         1     TRUE 150000     1   55 -3.668896 40.40165

Como vemos cada vivienda viene definida por su geolocalización y una serie de propiedades de ella, incluyendo el precio y superficie.

Taller: Precio de vivienda en Madrid

Los precios tienen mucha variabilidad

ggplot(precios_vivienda,aes(x=price)) + geom_density(fill="red") + scale_x_log10()

Taller: Precio de vivienda en Madrid

Quitamos las casas que valen menos de 50000€.

precios_vivienda <- precios_vivienda %>% filter(price>50000)

Así varía el precio por metro cuadrado

ggplot(precios_vivienda,aes(x=price/size)) + geom_density(fill="red") + scale_x_log10()

Taller: Precio de vivienda en Madrid

El precio varia entre

range(precios_vivienda$price)
## [1]    50106 40000000

Donde el precio medio por metro cuadrado es

mean(precios_vivienda$price/precios_vivienda$size)
## [1] 3042.672

Taller: Precio de vivienda en Madrid

Vamos a visualizar cómo depende el precio de la vivienda para cada uno de los barrios de Madrid. Para ello lo primero es situar cada inmueble en su barrio

Cargamos los shapefiles de los barrios de Madrid

map_barrios <- read_sf("./data/Barrios Madrid/200001469.shp")
map_barrios$DESBDT <- iconv(map_barrios$DESBDT,from="Windows-1252", to="UTF-8")

Como siempre utilizamos la proyección WGS84

mapb <- st_transform(map_barrios,4326)

Taller: Precio de vivienda en Madrid

Utilizamos la funcion st_within para saber en qué barrio está cada uno de los inmuebles

pts <- st_as_sf(precios_vivienda,coords = c("longitude","latitude"),crs=4326)
id_polygon <- st_within(pts,mapb)

Y añadimos una columna a los inmuebles que refleje su barrio

precios_vivienda$barrio <- mapb$DESBDT[as.numeric(id_polygon)]
head(precios_vivienda,3)
##   bathrooms exterior  price rooms size longitude latitude                barrio
## 1         1     TRUE  56050     3   60 -3.614164 40.40848            192 Ambroz
## 2         2     TRUE 160000     3  107 -3.641696 40.38688 134 Palomeras Sureste
## 3         2     TRUE 645000     3  154 -3.674424 40.42397              042 Goya

Taller: Precio de vivienda en Madrid

Calculamos el promedio del precio por metro cuadrado y el número de inmuebles para cada barrio

precios_barrio <- precios_vivienda %>% group_by(barrio) %>%
  summarise(precio_medio_m2=mean(price/size),num_inmuebles=length(price)) %>% ungroup()
head(precios_barrio,3)
## # A tibble: 3 × 3
##   barrio          precio_medio_m2 num_inmuebles
##   <chr>                     <dbl>         <int>
## 1 011 Palacio               3614.           426
## 2 012 Embajadores           3080.           574
## 3 013 Cortes                3839.           242

Ponemos esa información en los datos del mapa

mapb2 <- merge(mapb,precios_barrio,by.x="DESBDT",by.y="barrio")

Taller: Precio de vivienda en Madrid

Visualizamos el precio medio como un choropleth

pal <- colorNumeric(palette = "Blues",domain = mapb2$precio_medio_m2)
leaflet(mapb2) %>% addTiles() %>% 
  addPolygons(fillColor =~pal(precio_medio_m2),stroke = F,
              popup=~paste(DESBDT,"<br>",precio_medio_m2),fillOpacity = 0.9)

Taller: Modelización precio vivienda en Madrid

Como hemos visto, la principal variable que explica el precio de la vivienda es la superficie

ggplot(precios_vivienda,aes(x=size,y=price)) + geom_point() + stat_smooth() + scale_x_log10() + scale_y_log10()

Taller: Modelización precio vivienda en Madrid

Lo cual se refleja en un simple modelo

fit <- lm(log(price) ~ log(size), data=precios_vivienda)
summary(fit)
## 
## Call:
## lm(formula = log(price) ~ log(size), data = precios_vivienda)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -3.0661 -0.2976  0.0278  0.3185  3.9290 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 6.807184   0.017469   389.7   <2e-16 ***
## log(size)   1.232795   0.003666   336.2   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.4597 on 36160 degrees of freedom
## Multiple R-squared:  0.7577, Adjusted R-squared:  0.7577 
## F-statistic: 1.131e+05 on 1 and 36160 DF,  p-value: < 2.2e-16

Taller: Modelización precio vivienda en Madrid

¿Cómo influyen las otras propiedades del inmueble? Hacemos un modelo que incluya el número de habitaciones, si es exterior o no, etc

fit <- lm(log(price) ~ log(size) + rooms + as.factor(exterior)+bathrooms, data = precios_vivienda)
summary(fit)
## 
## Call:
## lm(formula = log(price) ~ log(size) + rooms + as.factor(exterior) + 
##     bathrooms, data = precios_vivienda)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -3.1996 -0.2877  0.0286  0.3026  3.8231 
## 
## Coefficients:
##                          Estimate Std. Error t value Pr(>|t|)    
## (Intercept)              6.894173   0.026703  258.18   <2e-16 ***
## log(size)                1.230833   0.007071  174.06   <2e-16 ***
## rooms                   -0.135325   0.002486  -54.44   <2e-16 ***
## as.factor(exterior)TRUE  0.059753   0.005426   11.01   <2e-16 ***
## bathrooms                0.139772   0.003348   41.75   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.437 on 36157 degrees of freedom
## Multiple R-squared:  0.7811, Adjusted R-squared:  0.781 
## F-statistic: 3.225e+04 on 4 and 36157 DF,  p-value: < 2.2e-16

Taller: Modelización precio vivienda en Madrid

Veamos ahora cómo influyen las variables de localización. Por ejemplo, la distancia al centro. Añadimos una columna a los datos que nos de la distancia al centro

pto_center <- st_as_sf(data.frame(lon=-3.7037,lat=40.416775),coords = c("lon","lat"),crs=4326)
pto_vivienda <- st_as_sf(precios_vivienda,coords=c("longitude","latitude"),crs=4326)
dist_center <- st_distance(pto_vivienda,pto_center)
pto_vivienda$dist_center <- as.numeric(dist_center)

Y modelizamos de nuevo

fit <- lm(log(price) ~ log(size) + rooms + as.factor(exterior) + 
            bathrooms + dist_center, data = pto_vivienda)
summary(fit)$coefficients
##                              Estimate   Std. Error   t value     Pr(>|t|)
## (Intercept)              7.168993e+00 2.533866e-02 282.92707 0.000000e+00
## log(size)                1.226012e+00 6.630386e-03 184.90806 0.000000e+00
## rooms                   -1.402372e-01 2.331811e-03 -60.14088 0.000000e+00
## as.factor(exterior)TRUE  5.498916e-02 5.087881e-03  10.80787 3.476631e-27
## bathrooms                1.612454e-01 3.153423e-03  51.13343 0.000000e+00
## dist_center             -5.416121e-05 7.680664e-07 -70.51631 0.000000e+00

Taller: Modelización precio vivienda en Madrid

Aunque el modelo ya es muy bueno, vamos a ver si el error es diferente por barrios

pto_vivienda$fitted <- fitted(fit)
error_barrios <- st_drop_geometry(pto_vivienda) %>% group_by(barrio) %>%
  summarize(MAE_medio=mean(abs(log(price)-fitted)/fitted))

donde vemos que hay barrios donde el modelo tiene mucho error

error_barrios %>% filter(MAE_medio > 0.04)
## # A tibble: 8 × 2
##   barrio              MAE_medio
##   <chr>                   <dbl>
## 1 121 Orcasitas          0.0438
## 2 122 Orcasur            0.0411
## 3 126 Zofío              0.0412
## 4 127 Pradolongo         0.0468
## 5 131 Entrevías          0.0555
## 6 132 San Diego          0.0420
## 7 133 Palomeras Bajas    0.0422
## 8 135 Portazgo           0.0416

Taller: Modelización precio vivienda en Madrid

Visualizamos ese error

mapb2 <- merge(mapb2,error_barrios,by.x="DESBDT",by.y="barrio")
pal <- colorNumeric(palette = "Blues",domain = mapb2$MAE_medio)
leaflet(mapb2) %>% addTiles() %>% 
  addPolygons(fillColor =~pal(MAE_medio),stroke = F,
              popup=~paste(DESBDT,"<br>",MAE_medio),fillOpacity = 0.9)

Ejercicio 1: Efecto de la distancia al metro

Vamos a ver si el que el inmueble esté cerca del metro tiene algún efecto en el precio. Para ello nos bajamos la geolocalización de las paradas de metro de Nomecalles

bocas <- read_sf("./data/Transportes y comunicaciones_ Metro (bocas)/bocas.shp")

Y las transformamos a lat/long

bocas2 <- st_transform(bocas,crs=4326)

Ejercicio 1: Efecto de la distancia al metro

Ahora tenemos que determinar la distancia a la boca de metro más cercana. Definimos una función que, a partir de un punto nos da la distancia más corta a una boca de metro

distance_boca <- function(pto){
  dd <- st_distance(pto,bocas2)
  apply(dd,1,FUN=min)
}

Por ejemplo la distancia a la boca más cercana del centro de la Puerta del Sol es

distance_boca(pto_center)
## [1] 21.78039

es decir, apenas unos metros

Ejercicio 1: Efecto de la distancia al metro

Calculamos la distancia a cada uno de los inmuebles

pto_vivienda <- pto_vivienda %>% mutate(distancia_metro=distance_boca(geometry))

Influye?

fit <- lm(log(price) ~ log(size) + rooms + as.factor(exterior) + 
            bathrooms + dist_center + distancia_metro, data = pto_vivienda)
summary(fit)$coefficients
##                              Estimate   Std. Error   t value     Pr(>|t|)
## (Intercept)              7.130012e+00 2.531217e-02 281.68320 0.000000e+00
## log(size)                1.235718e+00 6.621239e-03 186.62949 0.000000e+00
## rooms                   -1.427033e-01 2.325021e-03 -61.37722 0.000000e+00
## as.factor(exterior)TRUE  4.301024e-02 5.106649e-03   8.42240 3.822641e-17
## bathrooms                1.658670e-01 3.149096e-03  52.67132 0.000000e+00
## dist_center             -4.570702e-05 8.932289e-07 -51.17056 0.000000e+00
## distancia_metro         -8.705309e-05 4.755986e-06 -18.30390 1.673765e-74

Ejercicio 2: Efecto de la distancia a un supermercado

Repetir el ejercicio anterior para los supermercados, galerias de alimentación y mercadillos

Ejercicio 3: Visualización de oportunidades

  • Identificar los inmuebles que tienen un precio por metro cuadrado mucho menor que la media de su barrio

  • Visualizar dichos inmuebles en un mapa